package com.mybatis.service.impl;

import cn.hutool.core.io.FileUtil;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.mybatis.constant.Constants;
import com.mybatis.constant.DataSourceConstants;
import com.mybatis.dto.request.CodeGenerationParam;
import com.mybatis.strategy.DatabaseStrategy;
import com.mybatis.template.AbstractGeneratorTemplate;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.nio.file.Path;
import java.nio.file.Paths;

import static com.baomidou.mybatisplus.generator.config.rules.DateType.ONLY_DATE;

/**
 * @desc: 使用mybatis-plus生成代码
 * @projectName: mybatis-generator-parent
 * @author: xhs
 * @date: 2023-7-22 022 17:48
 * @version: JDK 1.8
 */
@Slf4j
@Service("mybatis-plus")
public class MybatisPlusCodeImpl extends AbstractGeneratorTemplate {

    /**
     * 生成代码
     *
     * @param codeGenerationParam 生成代码入参
     * @return boolean
     */
    @Override
    protected boolean getGenerator(CodeGenerationParam codeGenerationParam, DatabaseStrategy databaseStrategy) {
        // 项目根目录
        String projectPath = System.getProperty(Constants.USER_DIR);
        // 文件输出目录
        String outFilePath = projectPath + Constants.FILE_OUTPUT_DIR;
        Path dirPath = Paths.get(outFilePath);
        if (FileUtil.exists(dirPath, true)) {
            // 删除文件夹
            FileUtil.del(dirPath);
        }
        // 创建文件夹
        FileUtil.mkdir(dirPath);

        //判断数据库类型
        String url = null;
        String urlSuffix = codeGenerationParam.getDataBaseUrl()+Constants.COLON+codeGenerationParam.getDataBasePort()+Constants.SLASH + codeGenerationParam.getDataBaseName();
        if (DataSourceConstants.MYSQL.equals(codeGenerationParam.getDataBaseType())) {
            url = DataSourceConstants.MYSQL_URL + urlSuffix;
        }
        if (DataSourceConstants.ORACLE.equals(codeGenerationParam.getDataBaseType())) {
            url = DataSourceConstants.ORACLE_URL + urlSuffix;
        }

        FastAutoGenerator.create(url, codeGenerationParam.getDataBaseUserName(), codeGenerationParam.getDataBasePassword())
                // 全局配置
                .globalConfig(builder -> {
                    builder.author(codeGenerationParam.getAuthor()) // 作者
                            .outputDir(outFilePath) // 文件输出目录
                            .dateType(ONLY_DATE) // 时间策略
                            .commentDate("yyyy-MM-dd") // 注释日期
                            .build();
                })
                // 包配置
                .packageConfig(builder -> {
                    builder.parent(codeGenerationParam.getBasePackage()) // 父包名
                            .build();
                })
                // 策略配置
                .strategyConfig(builder -> {
                    // 增加表匹配
                    builder.addInclude(codeGenerationParam.getDataBaseTableName());
                    // entity策略配置
                    builder.entityBuilder()
                            .enableLombok()// 开启 lombok
                            .enableChainModel() // 开启链式模型
                            .enableFileOverride() // 覆盖已生成文件
                            .enableTableFieldAnnotation() // 开启生成实体时生成字段注解
                            .formatFileName("%sEntity") // 格式化Entity名称
                            .build();
                    // mapper策略配置
                    builder.mapperBuilder()
                            .enableFileOverride() // 覆盖已生成文件
                            .enableBaseResultMap() // 启用 BaseResultMap 生成
                            .build();
                    // service策略配置
                    builder.serviceBuilder()
                            .enableFileOverride() // 覆盖已生成文件
                            .formatServiceFileName("%sService") // 格式化 service 接口文件名称
                            .formatServiceImplFileName("%sServiceImp") // 格式化 service 实现类文件名称
                            .build();
                    // controller策略配置
                    builder.controllerBuilder()
                            .enableFileOverride() // 覆盖已生成文件
                            .enableRestStyle() // 开启生成@RestController 控制器
                            .build();
                })
                // 生成代码
                .execute();
        return true;
    }
}
